using Hangfire;
using WeatherSystem.API.Models;
using WeatherSystem.API.Services;
using WeatherSystem.API.Repositories;
using WeatherSystem.API.CQRS;
using WeatherSystem.API.CQRS.Commands;

namespace WeatherSystem.API.BackgroundJobs
{
    /// <summary>
    /// 后台作业服务实现
    /// </summary>
    public class BackgroundJobService : IBackgroundJobService
    {
        private readonly IBackgroundJobClient _backgroundJobClient;
        private readonly IRecurringJobManager _recurringJobManager;
        private readonly ILogger<BackgroundJobService> _logger;

        public BackgroundJobService(
            IBackgroundJobClient backgroundJobClient,
            IRecurringJobManager recurringJobManager,
            ILogger<BackgroundJobService> logger)
        {
            _backgroundJobClient = backgroundJobClient;
            _recurringJobManager = recurringJobManager;
            _logger = logger;
        }

        public async Task<string> EnqueueDataCollectionAsync()
        {
            var jobId = _backgroundJobClient.Enqueue<IBackgroundJobTaskService>(
                x => x.ExecuteDataCollectionAsync());
            
            _logger.LogInformation("数据采集作业已加入队列，作业ID: {JobId}", jobId);
            return await Task.FromResult(jobId);
        }

        public async Task<string> EnqueueCityDataCollectionAsync(Guid cityId)
        {
            var jobId = _backgroundJobClient.Enqueue<IBackgroundJobTaskService>(
                x => x.ExecuteCityDataCollectionAsync(cityId));
            
            _logger.LogInformation("城市数据采集作业已加入队列，城市ID: {CityId}, 作业ID: {JobId}", cityId, jobId);
            return await Task.FromResult(jobId);
        }

        public async Task<string> EnqueueStatisticsGenerationAsync()
        {
            var jobId = _backgroundJobClient.Enqueue<IBackgroundJobTaskService>(
                x => x.ExecuteStatisticsGenerationAsync());
            
            _logger.LogInformation("统计生成作业已加入队列，作业ID: {JobId}", jobId);
            return await Task.FromResult(jobId);
        }

        public async Task<string> EnqueueDataCleanupAsync()
        {
            var jobId = _backgroundJobClient.Enqueue<IBackgroundJobTaskService>(
                x => x.ExecuteDataCleanupAsync());
            
            _logger.LogInformation("数据清理作业已加入队列，作业ID: {JobId}", jobId);
            return await Task.FromResult(jobId);
        }

        public async Task<string> EnqueueWeatherReportGenerationAsync(Guid cityId, DateTime startDate, DateTime endDate)
        {
            var jobId = _backgroundJobClient.Enqueue<IBackgroundJobTaskService>(
                x => x.ExecuteWeatherReportGenerationAsync(cityId, startDate, endDate));
            
            _logger.LogInformation("天气报告生成作业已加入队列，城市ID: {CityId}, 作业ID: {JobId}", cityId, jobId);
            return await Task.FromResult(jobId);
        }

        public async Task<string> EnqueueBulkDataSimulationAsync(int recordsPerCity, double baseTemperature)
        {
            var jobId = _backgroundJobClient.Enqueue<IBackgroundJobTaskService>(
                x => x.ExecuteBulkDataSimulationAsync(recordsPerCity, baseTemperature));
            
            _logger.LogInformation("批量数据模拟作业已加入队列，记录数/城市: {Records}, 基础温度: {Temperature}, 作业ID: {JobId}", 
                recordsPerCity, baseTemperature, jobId);
            return await Task.FromResult(jobId);
        }

        public async Task<string> EnqueueCacheWarmupAsync()
        {
            var jobId = _backgroundJobClient.Enqueue<IBackgroundJobTaskService>(
                x => x.ExecuteCacheWarmupAsync());
            
            _logger.LogInformation("缓存预热作业已加入队列，作业ID: {JobId}", jobId);
            return await Task.FromResult(jobId);
        }

        public void SetupRecurringJobs()
        {
            try
            {
                // 每小时执行数据采集
                _recurringJobManager.AddOrUpdate(
                    "hourly-data-collection",
                    () => EnqueueDataCollectionAsync(),
                    "0 * * * *", // 每小时的第0分钟执行
                    new RecurringJobOptions 
                    { 
                        TimeZone = TimeZoneInfo.Local 
                    });

                // 每日午夜生成统计数据
                _recurringJobManager.AddOrUpdate(
                    "daily-statistics-generation",
                    () => EnqueueStatisticsGenerationAsync(),
                    "0 0 * * *", // 每天午夜执行
                    new RecurringJobOptions 
                    { 
                        TimeZone = TimeZoneInfo.Local 
                    });

                // 每周日凌晨3点执行数据清理
                _recurringJobManager.AddOrUpdate(
                    "weekly-data-cleanup",
                    () => EnqueueDataCleanupAsync(),
                    "0 3 * * 0", // 每周日凌晨3点执行
                    new RecurringJobOptions 
                    { 
                        TimeZone = TimeZoneInfo.Local 
                    });

                // 每天凌晨2点执行缓存预热
                _recurringJobManager.AddOrUpdate(
                    "daily-cache-warmup",
                    () => EnqueueCacheWarmupAsync(),
                    "0 2 * * *", // 每天凌晨2点执行
                    new RecurringJobOptions 
                    { 
                        TimeZone = TimeZoneInfo.Local 
                    });

                _logger.LogInformation("定期作业调度设置完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设置定期作业时发生错误");
                throw;
            }
        }

        public async Task<object> GetJobStatusAsync(string jobId)
        {
            try
            {
                // Hangfire 作业状态查询需要通过监控API实现
                // 这里提供一个简化的实现
                var status = new
                {
                    JobId = jobId,
                    Status = "Unknown", // 实际项目中可以通过 Hangfire 监控 API 获取具体状态
                    CreatedAt = DateTime.UtcNow,
                    Message = "作业状态查询功能需要完整的Hangfire监控集成"
                };

                return await Task.FromResult(status);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取作业状态时发生错误，作业ID: {JobId}", jobId);
                throw;
            }
        }

        public async Task<bool> CancelJobAsync(string jobId)
        {
            try
            {
                var result = _backgroundJobClient.Delete(jobId);
                _logger.LogInformation("作业取消请求已发送，作业ID: {JobId}, 结果: {Result}", jobId, result);
                return await Task.FromResult(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "取消作业时发生错误，作业ID: {JobId}", jobId);
                return false;
            }
        }

        public async Task<object> GetJobStatisticsAsync()
        {
            try
            {
                // 简化的作业统计信息
                var statistics = new
                {
                    TotalJobs = 0, // 实际项目中可以通过 Hangfire 统计API获取
                    ActiveJobs = 0,
                    CompletedJobs = 0,
                    FailedJobs = 0,
                    RecurringJobs = 4, // 我们设置了4个定期作业
                    LastUpdated = DateTime.UtcNow,
                    Message = "详细统计信息需要完整的Hangfire监控集成"
                };

                return await Task.FromResult(statistics);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取作业统计信息时发生错误");
                throw;
            }
        }
    }
}